父子通信
props和emit
父组件通过props传递数据给子组件,子组件通过emit发送事件传递给父组件。
// 父组件
<div>
<child :data="child" @send="getFromChild"></child>
</div>
data(){
return{
toChild: '大儿子',
fromChild: ''
}
},
methods: {
getFromChild(val){
this.fromChild=val
}
}
// 子组件
<div @click="toParent">{{data}}</div>
props:[data],
methods: {
toParent(){
this.$emit('send', '给父亲')
}
}
v-model
v-model其实是props,emit的语法糖,v-model默认会解析成名为value的prop和名为input的事件。
// 父组件
<children v-model="msg"></children>
<p>{{msg}}</p>
data(){
return{
msg:'model'
}
}
// 子组件
<input :value="value" @input="toInput" />
props: ['value'],
methods: {
toInput(e){
this.$emit('input', e.target.value)
}
}
如果想改变默认解析值,请使用model
Vue.component('base-checkbox', {
model: { prop: 'checked', event: 'change' },
props: { checked: Boolean },
template: \` <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > \`
})
$children和$parent
在父组件使用$children访问子组件,在子组件中使用$parent访问父组件
// 父组件
<child />
data(){
return {
msg: '父组件数据'
}
},
methods: {
test(){
console.log('我是父组件的方法,被执行')
}
},
mounted(){
console.log(this.$children[0].child_msg); // 执行子组件方法
}
// 子组件
<div>{{$parent.msg}}</div>
data(){
return{
child_msg: '子组件数据'
}
},
mounted(){
// 子组件执行父组件方法
this.$parent.test();
}
.sync方式
在vue1.x中是对prop进行双向绑定,在vue2只允许单向数据流,也是一个语法糖
// 父组件
<child :count.sync="num" />
data(){
return {
num: 0
}
}
// 子组件
<div @click="handleAdd">add</div>
data(){
return {
counter: this.count
}
},
props: ["count"],
methods: {
handleAdd(){
this.$emit('update:count', ++this.counter)
}
}
插槽
父组件:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template #default="slotProps">
{{ slotProps.user.name }}
</template>
</base-layout>
子组件:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<slot :user="user">
{{ user.name }}
</slot>
</div>
v-slot
只能在组件或template
标签上使用v-slot
缩写为#
跨多层次组件通信
依赖注入
可以使用provide/inject,虽然文档中不推荐直接使用在业务中。
假设有父组件A,然后有一个跨多层次的子组件B
// 父组件A
export default{
provide: {
data: 1
}
}
// 子组件B
export default{
inject: ['data'],
mounted(){
// 无论跨几层都能获取父组件的data属性
console.log(this.data); // 1
}
}
$listeners和$attrs
$attrs--包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
inheritAttrs--默认值true,继承所有父组件属性(除props),为true会将attrs中的属性当做html的data属性渲染到dom根节点上
$listeners--包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,v-on="$listeners"将所有事件监听器指向这个组件的某个特定子元素
// 父组件
<children :child1="child1" :child2="child2" @test1="onTest1"
@test2="onTest2"></children>
data(){
return {
child1: 'childOne',
child2: 'childTwo'
}
},
methods: {
onTest1(){
console.log('test1 running')
},
onTest2(){
console.log('test2 running')
}
}
// 子组件
<p>{{child1}}</p>
<child v-bind="$attrs" v-on="$listeners"></child>
props: ['child1'],
mounted(){
this.$emit('test1')
}
// 孙组件
<p>{{child2}</p>
<p>{{$attrs}}</p>
props: ['child2'],
mounted(){
this.$emit('test2')
}
任意组件
Event Bus
1.新建一个bus.js文件
import Vue from 'vue';
export default new Vue();
2.使用它
<div @click="addCart">添加</div>
import Bus from 'bus.js';
export default{
methods: {
addCart(event){
Bus.$emit('getTarget', event.target)
}
}
}
// 另一组件
export default{
created(){
Bus.$on('getTarget', target =>{
console.log(target)
})
}
}
Vue.observable
可以作为最小化跨组件状态化管理。
使用Vue.observable()进行状态管理
Vuex方式
参考链接:
https://juejin.im/post/5c776e...
https://segmentfault.com/a/11...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。